﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

namespace DynamicGeometry
{
    public class Factory
    {
        const int size = 8;

        public static Number CreateNumber(Drawing drawing, Func<double> valueProvider)
        {
            return new Number() { Drawing = drawing, Function = valueProvider };
        }

        public static Shape CreatePointShape()
        {
            Ellipse ellipse = new Ellipse()
            {
                Width = size,
                Height = size,
                Fill = new SolidColorBrush(Colors.Yellow),
                Stroke = new SolidColorBrush(Colors.Black),
                StrokeThickness = 0.5
            };

            return ellipse;
        }

        public static Shape CreateDependentPointShape()
        {
            Ellipse ellipse = new Ellipse()
            {
                Width = size,
                Height = size,
                Fill = new SolidColorBrush(Color.FromArgb(255, 240, 240, 240)),
                Stroke = new SolidColorBrush(Colors.Black),
                StrokeThickness = 0.5
            };

            return ellipse;
        }

        public static Shape CreateCircleShape()
        {
            int size = 8;
            Ellipse ellipse = new Ellipse()
            {
                Width = size,
                Height = size,
                Stroke = new SolidColorBrush(Colors.Black),
                StrokeThickness = 1
            };

            return ellipse;
        }

        public static System.Windows.Shapes.Polygon CreatePolygonShape()
        {
            return new System.Windows.Shapes.Polygon()
            {
                Fill = CreateDefaultFillBrush()
            };
        }

        public static Brush CreateDefaultFillBrush()
        {
            return new SolidColorBrush(Color.FromArgb(255, 255, 255, 200));
        }

        public static Brush CreateGradientBrush(Color c1, Color c2, double angle)
        {
            LinearGradientBrush result = new LinearGradientBrush(
                new GradientStopCollection()
                {
                    new GradientStop() { Offset = 0.1, Color = c1 },
                    new GradientStop() { Offset = 1.0, Color = c2 }
                }, angle);
            return result;
        }

        public static Line CreateLineShape()
        {
            Line result = new Line()
            {
                Stroke = new SolidColorBrush(Colors.Black),
                StrokeThickness = 1
            };

            return result;
        }

        public static TextBlock CreateLabelShape()
        {
            return new TextBlock()
            {

            };
        }

        public static MidPoint CreateMidPoint(Drawing drawing, IFigureList dependencies)
        {
            MidPoint result = new MidPoint() { Drawing = drawing, Dependencies = dependencies };
            return result;
        }

        public static LineTwoPoints CreateLineTwoPoints(Drawing drawing, IFigureList dependencies)
        {
            return new LineTwoPoints() { Drawing = drawing, Dependencies = dependencies };
        }

        public static FreePoint CreateFreePoint(Drawing drawing, Point coordinates)
        {
            FreePoint result = new FreePoint() { Drawing = drawing };
            result.MoveTo(coordinates);
            return result;
        }

        public static Segment CreateSegment(Drawing drawing, FigureList dependencies)
        {
            return new Segment() { Drawing = drawing, Dependencies = dependencies };
        }

        public static Ray CreateRay(Drawing drawing, FigureList dependencies)
        {
            return new Ray() { Drawing = drawing, Dependencies = dependencies };
        }

        public static Circle CreateCircle(Drawing drawing, FigureList dependencies)
        {
            return new Circle() { Drawing = drawing, Dependencies = dependencies };
        }

        public static CircleByRadius CreateCircleByRadius(Drawing drawing, FigureList dependencies)
        {
            return new CircleByRadius() { Drawing = drawing, Dependencies = dependencies };
        }

        public static ParallelLine CreateParallelLine(Drawing drawing, FigureList dependencies)
        {
            return new ParallelLine() { Drawing = drawing, Dependencies = dependencies };
        }

        public static IFigure CreatePerpendicularLine(Drawing drawing, FigureList dependencies)
        {
            return new PerpendicularLine() { Drawing = drawing, Dependencies = dependencies };
        }

        public static IntersectionPoint CreateIntersectionPoint(
            Drawing drawing, IFigure figure1, IFigure figure2, Point hintPoint)
        {
            return new IntersectionPoint(hintPoint, new FigureList() { figure1, figure2 }) { Drawing = drawing };
        }

        public static PointOnFigure CreatePointOnFigure(Drawing drawing, IFigure iFigure, Point point)
        {
            var result = new PointOnFigure()
            {
                Drawing = drawing,
                Dependencies = new FigureList() { iFigure },
            };
            result.Parameter = result.LinearFigure.GetNearestParameterFromPoint(point);
            return result;
        }

        public static SymmPoint CreateSymmPoint(Drawing drawing, FigureList dependencies)
        {
            return new SymmPoint() { Drawing = drawing, Dependencies = dependencies };
        }

        public static DistanceMeasurement CreateDistanceMeasurement(Drawing drawing, FigureList dependencies)
        {
            return new DistanceMeasurement() { Drawing = drawing, Dependencies = dependencies };
        }

        public static CoordinatesMeasurement CreateCoordinatesMeasurement(Drawing drawing, FigureList dependencies)
        {
            return new CoordinatesMeasurement() { Drawing = drawing, Dependencies = dependencies };
        }

        public static Label CreateLabel(Drawing drawing, FigureList dependencies)
        {
            return new Label() { Drawing = drawing, Dependencies = dependencies };
        }

        public static Polygon CreatePolygon(Drawing drawing, FigureList dependencies)
        {
            var result = new Polygon() { Drawing = drawing, Dependencies = dependencies };
            return result;
        }

        public static AngleMeasurement CreateAngleMeasurement(Drawing drawing, FigureList dependencies)
        {
            return new AngleMeasurement() { Drawing = drawing, Dependencies = dependencies };
        }

        public static AngleArc CreateAngleArc(Drawing drawing, FigureList dependencies)
        {
            return new AngleArc() { Drawing = drawing, Dependencies = dependencies };
        }

        public static AreaMeasurement CreateAreaMeasurement(Drawing drawing, FigureList dependencies)
        {
            return new AreaMeasurement() { Drawing = drawing, Dependencies = dependencies };
        }

        public static PointByCoordinates CreatePointByCoordinates(Drawing drawing, FigureList dependencies)
        {
            return new PointByCoordinates() { Drawing = drawing, Dependencies = dependencies };
        }

        public static PointByCoordinates CreatePointByCoordinates(Drawing drawing, Func<double> xValueProvider, Func<double> yValueProvider)
        {
            return new PointByCoordinates() { Drawing = drawing, XValueProvider = xValueProvider, YValueProvider = yValueProvider };
        }

        public static Axis CreateAxis(Drawing drawing, FigureList dependencies)
        {
            var result = new Axis() { Drawing = drawing };
            result.Line.Dependencies = dependencies;
            return result;
        }

        public static Locus CreateLocus(Drawing Drawing, FigureList dependencies)
        {
            var result = new Locus() { Drawing = Drawing, Dependencies = dependencies };
            return result;
        }

        public static Arc CreateArc(Drawing drawing, FigureList foundDependencies)
        {
            var result = new Arc() { Drawing = drawing, Dependencies = foundDependencies };
            return result;
        }

        public static Tuple<Path, PathFigure, ArcSegment> CreateArcShape()
        {
            var arcSegment = new ArcSegment()
            {
                SweepDirection = SweepDirection.Counterclockwise,
                RotationAngle = 0
            };
            var figure = new PathFigure()
            {
                IsClosed = false,
                IsFilled = false,
                Segments = new PathSegmentCollection()
                {
                    arcSegment
                }
            };
            var path = new Path()
            {
                Data = new PathGeometry()
                {
                    Figures = new PathFigureCollection()
                    {
                        figure
                    }
                },
                Stroke = new SolidColorBrush(Colors.Black),
                StrokeThickness = 1
            };
            return Tuple.Create(path, figure, arcSegment);
        }
    }
}
